package com.beiding.natago2.store;

import com.beiding.natago2.utils.CommonUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 存储外部通道
 */
public class ChannelStore {

    /**
     * 全部通道
     */
    private Map<Long, ChannelHandlerContext> store = new ConcurrentHashMap<>();

    /**
     * id key
     */
    private static final AttributeKey<Long> ID_KEY = AttributeKey.newInstance("id");

    /**
     * 内部通道 key
     */
    private static final AttributeKey<ChannelHandlerContext> INNER_KEY = AttributeKey.newInstance("inner");

    /**
     * 目标通道是否存活
     * @param channelHandlerContext
     * @return
     */
    public boolean isActive(ChannelHandlerContext channelHandlerContext) {
        return store.containsKey(getId(channelHandlerContext));
    }

    /**
     * 目标通道是否存活
     * @param id
     * @return
     */
    public boolean isActive(Long id) {
        return store.containsKey(id);
    }

    /**
     * 目标通道加入
     * @param channelHandlerContext
     */
    public void put(ChannelHandlerContext channelHandlerContext) {
        store.put(getId(channelHandlerContext), channelHandlerContext);
    }

    /**
     * 设置目标通道的ID,自动生成ID
     * @param channelHandlerContext
     */
    public void setId(ChannelHandlerContext channelHandlerContext) {
        setId(channelHandlerContext, CommonUtil.createId());
    }

    /**
     * 设置目标通道的ID
     * @param channelHandlerContext
     * @param id
     */
    public void setId(ChannelHandlerContext channelHandlerContext,Long id) {
        channelHandlerContext.channel().attr(ID_KEY).set(id);
    }

    /**
     * 获取目标通道的ID
     * @param channelHandlerContext
     * @return
     */
    public Long getId(ChannelHandlerContext channelHandlerContext) {
        if (channelHandlerContext.channel().hasAttr(ID_KEY)) {
            return channelHandlerContext.channel().attr(ID_KEY).get();
        }
        return null;
    }

    /**
     * 获取一个目标通道
     * @param id
     * @return
     */
    public ChannelHandlerContext get(Long id) {
        return store.get(id);
    }

    /**
     * 关闭一个目标通道
     * @param id
     */
    public void close(Long id) {
        ChannelHandlerContext channelHandlerContext = store.remove(id);
        if (channelHandlerContext != null) {
            channelHandlerContext.close();
        }
    }

    /**
     * 关闭一个目标通道
     * @param channelHandlerContext
     */
    public void close(ChannelHandlerContext channelHandlerContext) {
        remove(channelHandlerContext);
        channelHandlerContext.close();
    }

    /**
     * 移除一个目标通道
     * @param id
     */
    public void remove(Long id) {
        store.remove(id);
    }


    /**
     * 移除一个目标通道
     * @param ctx
     */
    public void remove(ChannelHandlerContext ctx) {
        store.remove(getId(ctx));
    }

    /**
     * 绑定内部通道
     * @param ctx
     * @param channel
     */
    public void bindInner(ChannelHandlerContext ctx, ChannelHandlerContext channel) {
        ctx.channel().attr(INNER_KEY).set(channel);
    }

    /**
     * 获取一个通道的内部通道
     * @param ctx
     * @return
     */
    public ChannelHandlerContext getInner(ChannelHandlerContext ctx) {
        return ctx.channel().attr(INNER_KEY).get();
    }
}
